<?php

/** 
 * @Author: 李红雨 - RainLee <rainlee1990@yeah.net>
 * @Date: 2022-06-21 14:23:21
 * @LastEditors: 李红雨 - RainLee <rainlee1990@yeah.net>
 * @LastEditTime: 2022-06-21 16:04:25
 * @Description: File Description
 */

namespace rainlee\authn;

use think\facade\Request;

class NodeDrive
{

    protected $check_all = true;

    protected $nodes = [];

    public function __construct($config)
    {
        $this->check_all = $config['check_all'] ?? true;
        $this->nodes     = $config['check_node'] ?? [];
    }

    public function ignored()
    {
        if (empty($this->nodes)) $result = false;

        $path = Request::pathinfo();
        $result = false;
        foreach ($this->nodes as $node) {
            if ($this->checkMatch($path, $node)) {
                $result = true;
                break;
            }
        }
        if (!$this->check_all) {
            return !$result;
        }
        return $result;
    }

    /**
     * 检测URL和规则是否匹配
     * @access public
     * @param  string    $url  URL地址
     * @param  string    $rule 规则
     * @return array|false
     */
    public function checkMatch(string $url, string $rule)
    {
        [$method, $rule] = $this->resolveRule($rule);
        if (!in_array(strtoupper(Request::method()), $method)) {
            return false;
        }

        $depr = '/';

        if ($depr == $rule && $depr != $url) {
            return false;
        }
        $rule = str_replace('/', '\/', str_replace("\/", "/", $rule));
        if (preg_match("/^{$rule}$/", $url)) {
            return true;
        }
        return false;
    }

    /**
     * 解析规则
     * @access public
     * @param  string      $rule 规则
     * @return array
     */
    protected function resolveRule(string $rule)
    {
        if (false === strpos($rule, ':')) {
            $method = Request::method();
        } else {
            [$method, $rule] = explode(':', $rule, 2);
        }

        $method = explode('|', $method);

        foreach ($method as &$value) {
            $value = strtoupper($value);
        }

        $rule = '/' != $rule ? ltrim($rule, '/') : '';

        return [$method, $rule];
    }
}
